home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
biblio
/
bibtex
/
contrib
/
v0_98
/
btxbst.doc
< prev
next >
Wrap
Text File
|
1990-10-02
|
58KB
|
2,315 lines
%NAME: btxbst.doc
# if 0
% BibTeX `plain' family
% modified to ouput fields in French; shapiro@corto.inria.fr 30-oct-87
% Further modified for 'alpha3' and 'long' styles 3-nov-87
% and for 'key' and 'skey' 1-jan-88
% and for `paren' 23-march-89
# endif 0
% version 0.98c for BibTeX versions 0.98i or later, LaTeX version 2.08
% Copyright (C) 1985, all rights reserved
% Copying of this file is authorized only if either
% (1) you make absolutely no changes to your copy, including name, or
% (2) if you do make changes, you name it something other than
% btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst
% This restriction helps ensure that all standard styles are identical
# if 0
% This is file btxbxt.doc; it helps document bibliography styles,
% and is also a template file that you can use to make
% several different style files, if you have access to a C preprocessor.
% For example, the standard styles were made by something like
% cpp -P -DPLAIN btxbst.doc | sed -e '/^$/d' > plain.bst
% cpp -P -DUNSRT btxbst.doc | sed -e '/^$/d' > unsrt.bst
% cpp -P -DALPHA btxbst.doc | sed -e '/^$/d' > alpha.bst
% cpp -P -DABBRV btxbst.doc | sed -e '/^$/d' > abbrv.bst
% A French version of (say) abbrv is created by
% cpp -P -DABBRV -DFRENCH btxbst.doc | sed -e '/^$/d' > fabbrv.bst
% There are also new styles created by defining ALPHA3, KEY, SKEY,
% LONG, or PAREN. For each style respectivley the label is:
% ALPHA3 first 3 letters of 1st author's name + year [Lam85]
% LONG 1st author's full name + year [Lamport 85]
% PAREN 1st author's name + date in parenthesis [Lamport (85)]
% KEY the bibtex key, the bibliogrpahy is unsorted [latex:book]
% SKEY the bibtex key, sorted by 1st author's name&year [latex:book]
% The last two styles are intended for printing the database itself.
%
% If you don't have access to cpp you can edit this file by hand to
% imitate the preprocessor, with the following explanation of the C
% preprocessor constructs used here.
%
% The output of the preprocessor is the same as the input, except that certain
% lines will be excluded (and some blank lines will be added). The sequence
% #if VAR
% lines to be included when VAR is not zero
% #else
% lines to be included when VAR is zero
% #endif
% (with the #-signs appearing in column 1) means that one set or the other of
% the lines are to be included depending on the value of VAR.
% The #else part is optional. Comments can be added after #else and #endif.
% The '# if 0' ... '#endif' sequence is used to eliminate unnecessary
% comments from the output.
% Variables can be set by
% #define VAR value
% and one can also use #ifdef VAR to see if VAR has any value, and #ifndef
% to see if it has none.
% Another #if form used in this file is #if !VAR, which includes the lines
% after the #if only if VAR is zero.
%
% Convention: Use all uppercase identifiers for these preprocessor variables
% so you can spot them easily
%
% The command line to the preprocessor should define one of PLAIN, UNSRT, ALPHA
% or ABBRV (though PLAIN will be used by default if none is given),
% and the following lines will set various boolean variables to control the
% various lines that are chosen from the rest of the file.
% Each boolean variable should be set true (1) or false (0) in each style.
% Here are the current variables, and their meanings:
% LAB_ALPH: an alphabetic label is used (if false then a numeric
% label is used)
% SORTED: the entries should be sorted by label (if nonnumeric)
% and other info, like authors (if false, then
% entries remain in order of occurrence)
% NAME_FULL: the authors, editors, etc., get the full names as
% given in the bibliograph (if false, the first
% names become initials)
% ATIT_LOWER: titles of non-"books" (e.g., articles) should be
% converted to lower-case, except the first letter
% (if false then they appear as in the database)
% MONTH_FULL: months are spelled out in full (if false, then
% they're abbreviated)
% JOUR_FULL: macro journal names are spelled out in full
% (if false then they are abbreviated, currently
% as they appear in ACM publications)
% LBKEYS: use the database key as the citation label
% Furthermore the variable ALPHA_LONG may have one of the following
% values, when LAB_ALPH is 1, giving the following citation alphabetic
% label format:
% 0 [Lam85] for single author (or editor or key): first 3 letters of last name
% [SW79] (first letters of last names) for multiple authors
% 1 [Lam85] for single author (or editor or key)
% [Str79] (first 3 letters of 1st author's last name) for multiple authors
% 2 [Lamport 85] for single author (or editor or key): full last name
% [Strunk 79] (full last name of 1st author) for multiple authors
# endif 0
#ifndef UNSRT
# ifndef ALPHA
# ifndef ABBRV
# ifndef ALPHA3
# ifndef LONG
# ifndef KEY
# ifndef SKEY
# ifndef PAREN
# define PLAIN 1
# endif
# endif
# endif
# endif
# endif
# endif
# endif
#endif
#ifdef PLAIN
% plain style (sorted numbers)
# define LAB_ALPH 0
# define SORTED 1
# define NAME_FULL 1
# define ATIT_LOWER 1
# define MONTH_FULL 1
# define JOUR_FULL 1
# define LBKEYS 0
#endif
#ifdef UNSRT
% unsrt style (unsorted numbers)
# define LAB_ALPH 0
# define SORTED 0
# define NAME_FULL 1
# define ATIT_LOWER 1
# define MONTH_FULL 1
# define JOUR_FULL 1
# define LBKEYS 0
#endif
#ifdef ALPHA
% alpha style (sorted short alphabetics)
# define LAB_ALPH 1
# define ALPHA_LONG 0
# define SORTED 1
# define NAME_FULL 1
# define ATIT_LOWER 1
# define MONTH_FULL 1
# define JOUR_FULL 1
# define LBKEYS 0
#endif
#ifdef ALPHA3
% alpha3 style (sorted short alphabetics, 3 letters of 1st author only)
# define LAB_ALPH 1
# define ALPHA_LONG 1
# define SORTED 1
# define NAME_FULL 1
# define ATIT_LOWER 1
# define MONTH_FULL 1
# define JOUR_FULL 1
# define LBKEYS 0
#endif
#if defined(LONG) || defined(PAREN)
# ifdef LONG
% long style (sorted long alphabetics, full name of 1st author only)
# else
% parenthesised style ( (sorted long alphabetics, full name of 1st author only)
# endif
# define LAB_ALPH 1
# define ALPHA_LONG 2
# define SORTED 1
# define NAME_FULL 1
# define ATIT_LOWER 1
# define MONTH_FULL 1
# define JOUR_FULL 1
# define LBKEYS 0
#endif
#ifdef ABBRV
% abbrv style (sorted numbers, with abbreviations)
# define LAB_ALPH 0
# define SORTED 1
# define JOUR_FULL 0
# define MONTH_FULL 0
# define ATIT_LOWER 1
# define NAME_FULL 0
# define LBKEYS 0
#endif
#ifdef KEY
% keys style (unsorted keys)
# define LAB_ALPH 1
# define ALPHA_LONG 2
# define SORTED 0
# define NAME_FULL 0
# define ATIT_LOWER 1
# define MONTH_FULL 0
# define JOUR_FULL 1
# define LBKEYS 1
#endif
#ifdef SKEY
% skeys style (keys, sorted by name of 1st author and year)
# define LAB_ALPH 1
# define ALPHA_LONG 2
# define SORTED 1
# define NAME_FULL 1
# define ATIT_LOWER 1
# define MONTH_FULL 0
# define JOUR_FULL 1
# define LBKEYS 1
#endif
#ifdef FRENCH
% French version
#endif FRENCH
%
# if 0
% Entry formatting: Similar to that recommended by Mary-Claire van Leunen
% in "A Handbook for Scholars". Book-like titles are italicized and
% non-book titles are converted to sentence capitilization
% (and not enclosed in quotes).
% This file outputs a \newblock between major blocks of an entry
% (the name \newblock is analogous to the names \newline and \newpage)
% so that the user can obtain an "open" format, which has a line break
% before each block and lines after the first are indented within blocks,
% by giving an optional \documentstyle argument; currently there is a
% required `optional' \documentstyle argument, one of
% opbiba, opbibr, clbiba, or clbibr,
% giving an open or closed format for an article or report.
% For the next version of LaTeX there will be just one, truly optional
% style, for the open format
% (among other things, it will have improved page breaking).
% The default will be the "closed" format---blocks runs together.
%
% Citation alphabetic label format:
% [Knu73] for single author (or editor or key)
% [AHU83] (first letters of last names) for multiple authors
%
% Citation label numberic format:
% [number]
%
% Reference list ordering for sorted, alphabetic lables:
% alphabetical by citation label, then by author(s) or whatever
% passes for author in the absence of one, and then by title.
%
% Reference list ordering for sorted, numeric lables:
% alphabetical by author(s) or whatever passes
% passes for author in the absence of one, and then by title.
%
% Reference list ordering for unsorted:
% by the order cited in the text
%
% History
% 12/16/84 (HWT) Original `plain' version, by Howard Trickey.
% 12/23/84 (LL) Some comments made by Leslie Lamport.
% 2/16/85 (OP) Changes based on LL's comments, Oren Patashnik
% 2/17/85 (HWT) template file and other standard styles made
% 3/28/85 First release, version 0.98b for BibTeX 0.98f
% 5/ 9/85 version 0.98c for BibTeX 0.98i
% : fixed Theoretical Computer Science macro name
% : fixed the format.vol.num.pages function
%
% The ENTRY declaration
% Like Scribe's (according to pages 231-2 of the April '84 edition),
% but no fullauthor or editors fields because BibTeX does name handling.
% The annote field is commented out here because this family doesn't
% include an annotated bibliography style
# endif 0
ENTRY
% Fields:
{ address
% Publisher's address
% annote
% Long annotation used for annotated bibliographies (begins sentence)
author
% Name(s) of author(s), in BibTeX name format
booktitle
% Book title when the thing being referenced isn't the whole book.
% For book entries, the title field should be used instead.
chapter
% Chapter number
edition
% Edition of a book (e.g., "second")
editor
% Name(s) of editor(s), in BibTeX name format.
% If there is also an author field, then the editor field should be
% for the book or collection that the work appears in
howpublished
% How something strange has been published (begins sentence)
institution
% Sponsoring institution
journal
% Journal name (macros are provided for many)
key
% Alphabetizing and labeling key (needed when no author or editor)
month
% Month (macros are provided)
note
% To help the reader find a reference (begins sentence)
number
% Number of a journal or technical report
organization
% Organization (sponsoring a conference)
pages
% Page number or numbers (use `--' to separate a range)
publisher
% Publisher name
school
% School name (for theses)
series
% The name of a series or set of books.
% An individual book will will also have it's own title
title
% The title of the thing being referenced
type
% Type of a Techreport (e.g., "Research Note") to be used instead of
% the default "Technical Report"
volume
% Volume of a journal or multivolume work
year
% Year---should contain only numerals
}
# if 0
% There are no integer entry variables
# endif 0
{}
# if 0
% These string entry variables are used to form the citation label.
% In a storage pinch, sort.label can be easily computed on the fly.
# endif 0
#if LAB_ALPH
#if SORTED
{ label extra.label sort.label }
#else !SORTED
# if 0
% It still doesn't seem like a good idea to use an order-of-citation
% reference list when using alphabetic labels, but when this happens we
% do things a little differently
# endif 0
{label}
#endif SORTED
#else !LAB_ALPH
{label}
#endif LAB_ALPH
# if 0
% Each entry function starts by calling output.bibitem, to write the
% \bibitem and its arguments to the .BBL file. Then the various fields
% are formatted and printed by output or output.check. Those functions
% handle the writing of separators (commas, periods, \newblock's),
% taking care not to do so when they are passed a null string.
% Finally, fin.entry is called to add the final period and finish the
% entry.
%
% A bibliographic reference is formatted into a number of `blocks':
% in the open format, a block begins on a new line and subsequent
% lines of the block are indented. A block may contain more than
% one sentence (well, not a grammatical sentence, but something to
% be ended with a sentence ending period). The entry functions should
% call new.block whenever a block other than the first is about to be
% started. They should call new.sentence whenever a new sentence is
% to be started. The output functions will ensure that if two
% new.sentence's occur without any non-null string being output between
% them then there won't be two periods output. Similarly for two
% successive new.block's.
%
% The output routines don't write their argument immediately.
% Instead, by convention, that argument is saved on the stack to be
% output next time (when we'll know what separator needs to come
% after it). Meanwhile, the output routine has to pop the pending
% output off the stack, append any needed separator, and write it.
%
% To tell which separator is needed, we maintain an output.state.
% It will be one of these values:
% before.all just after the \bibitem
% mid.sentence in the middle of a sentence: comma needed
% if more sentence is output
% after.sentence just after a sentence: period needed
% after.block just after a block (and sentence):
% period and \newblock needed.
% Note: These styles don't use after.sentence
%
% VAR: output.state : INTEGER -- state variable for output
%
% The output.nonnull function saves its argument (assumed to be nonnull)
% on the stack, and writes the old saved value followed by any needed
% separator. The ordering of the tests is decreasing frequency of
% occurrence.
%
% output.nonnull(s) ==
% BEGIN
% s := argument on stack
% if output.state = mid.sentence then
% write$(pop() * ", ")
% -- "pop" isn't a function: just use stack top
% else
% if output.state = after.block then
% write$(add.period$(pop()))
% newline$
% write$("\newblock ")
% else
% if output.state = before.all then
% write$(pop())
% else -- output.state should be after.sentence
% write$(add.period$(pop()) * " ")
% fi
% fi
% fi
% push s on stack
% output.state := mid.sentence
% END
%
% The output function calls output.nonnull if its argument is non-null
%
% output(s) ==
% BEGIN
% if s <> "" then output.nonnull(s)
% fi
% END
%
% The output.check function calls output.nonnull if s is non-null
% and warns the user that the t field shouldn't be empty (this is
% because it won't be a good reference without the field; the entry
% functions try to make the formatting look reasonable even when such
% fields are empty).
%
% output.check(t,s) ==
% BEGIN
% if s = "" then
% top$("Warning: the " * t * " shouldn't be empty in " * cite$)
% else output.nonnull(s)
% fi
% END
%
% The output.bibitem function writes the \bibitem for the current entry
% (the label should already have been set up), and sets up the separator
% state for the output functions. And, it leaves a string on the stack
% as per the output convention.
%
% output.bibitem ==
% BEGIN
% newline$
% write$("\bibitem[") % for alphabetic labels,
% write$(label) % these three lines
% write$("]{") % are used
% write$("\bibitem{") % this line for numeric labels
% write$(cite$)
% write$("}")
% push "" on stack
% output.state := before.all
% END
%
% The fin.entry function finishes off an entry by adding a period to the
% string remaining on the stack. If the state is still before.all
% then nothing was produced for this entry, so the result will look bad,
% but the user deserves it. (We don't omit the whole entry because the
% entry was cited, and a bibitem is needed to define the citation label.)
%
% fin.entry ==
% BEGIN
% write$(add.period$(pop()))
% newline$
% END
%
% The new.block function prepares for a new block to be output, and
% new.sentence prepares for a new sentence.
%
% new.block ==
% BEGIN
% if output.state <> before.all then
% output.state := after.block
% fi
% END
%
% new.sentence ==
% BEGIN
% if output.state <> after.block then
% if output.state <> before.all then
% output.state := after.sentence
% fi
% fi
% END
%
# endif 0
INTEGERS { output.state before.all mid.sentence after.sentence after.block }
FUNCTION {init.state.consts}
{ 'before.all #0 :=
'mid.sentence #1 :=
'after.sentence #2 :=
'after.block #3 :=
}
# if 0
% the variables s and t are temporary string holders
# endif 0
STRINGS { s t }
FUNCTION {output.nonnull}
{ 's swap$ :=
output.state mid.sentence =
{ ", " * write$ }
{ output.state after.block =
{ add.period$ write$
newline$
"\newblock " write$
}
{ output.state before.all =
'write$
{ add.period$ " " * write$ }
if$
}
if$
}
if$
'output.state mid.sentence :=
s
}
FUNCTION {output}
{ 's swap$ :=
s "" =
'skip$
{ s output.nonnull }
if$
}
FUNCTION {output.check}
{ 's swap$ :=
't swap$ :=
s "" =
{ "Warning: the " t * " shouldn't be empty in " * cite$ * top$ }
{ s output.nonnull }
if$
}
FUNCTION {output.bibitem}
{ newline$
#if LAB_ALPH
"\bibitem[" write$
label write$
"]{" write$
#else
"\bibitem{" write$
#endif
cite$ write$
"}" write$
newline$
""
'output.state before.all :=
}
# if 0
% This function finishes all entries. Note: For an otherwise empty entry
% (which is probably due to a user error) this function prints a
period
# endif 0
FUNCTION {fin.entry}
{ add.period$
write$
newline$
}
FUNCTION {new.block}
{ output.state before.all =
'skip$
{ 'output.state after.block := }
if$
}
# if 0
% This function isn't used in these styles
# endif 0
FUNCTION {new.sentence}
{ output.state after.block =
'skip$
{ output.state before.all =
'skip$
{ 'output.state after.sentence := }
if$
}
if$
}
# if 0
% These three functions pop one or two (integer) arguments from the stack
% and push a single one, either 0 or 1.
% The 'skip$ in the `and' and `or' functions are used because
% the corresponding if$ would be idempotent
# endif 0
FUNCTION {not}
{ { #0 }
{ #1 }
if$
}
FUNCTION {and}
{ 'skip$
{ pop$ #0 }
if$
}
FUNCTION {or}
{ { pop$ #1 }
'skip$
if$
}
# if 0
% Here are some functions for formatting chunks of an entry.
% By convention they either produce a string that can be followed by
% a comma or period (using add.period$, so it is OK to end in a period),
% or they produce the null string.
%
% A useful utility is the field.or.null function, which checks if the
% argument is the result of pushing a `missing' field (one for which no
% assignment was made when the current entry was read in from the database),
% and returns the null string if so, otherwise it returns the field string.
%
% field.or.null(s) ==
% BEGIN
% if missing$(s) then return ""
% else return s
% END
%
% Another helper function is italicize, which returns the string that
% italicizes the argument string, if that is non-null, otherwise it
% returns the null string. Italic corrections aren't used, so this
% function should be used when punctation will follow the result.
% Also, it needn't be \em (instead of \it) because the user shouldn't be
% emphasizing the whole bibliography.
%
% italicize(s) ==
% BEGIN
% if s = "" then return ""
% else return "{\it " * s * "}"
%
% The format.names function formats the argument (which should be in
% BibTeX name format) into "First Von~Last, Junior", separated by commas
% and with an "and" before the last (but ending with "et al." if the last
% of multiple authors is "others")
%
% VAR: nameptr, namesleft, numnames: INTEGER
% nameresult: STRING
%
% format.names(s) ==
% BEGIN
% nameptr := 1
% nameresult := ""
% numnames := num.names$(s)
% namesleft := numnames
% while namesleft > 0
% do
% % for full names:
% t := format.name$(s, nameptr, "{ff }{vv~}{ll}{, jj}")
% % for abbreviated first names:
% t := format.name$(s, nameptr, "{f.~}{vv~}{ll}{, jj}")
% if nameptr > 1 then
% if namesleft > 1 then nameresult := nameresult * ", " * t
% else if numnames > 2
% then nameresult := nameresult * ","
% fi
% if t = "others"
% then nameresult := nameresult * " et al."
% else nameresult := nameresult * " and " * t
% fi
% fi
% else nameresult := nameresult * t
% fi
% nameptr := nameptr + 1
% namesleft := namesleft - 1
% od
% return nameresult
% END
%
% The format.authors function returns the result of format.names(author)
% if the author is present, or else it returns the null string
%
% format.authors ==
% BEGIN
% if missing$(author) then return ""
% else return format.names(author)
% fi
% END
%
% Format.editors is like format.authors, but it uses the editor field,
% and appends ", editor" or ", editors"
%
% format.editors ==
% BEGIN
% if missing$(editor) then return ""
% else
% if num.names$(editor) > 1 then
% return format.names(editor) * ", editors"
% else
% return format.names(editor) * ", editor"
% fi
% fi
% END
%
% Other formatting functions are similar, so no "comment version" will be
% given for them.
%
% The `pop$' in this function gets rid of the duplicate `missing' value and
% the `skip$' returns the duplicate field value
# endif 0
FUNCTION {field.or.null}
{ duplicate$
missing$
{ pop$ "" }
'skip$
if$
}
FUNCTION {italicize}
{ 's swap$ :=
s "" =
{ "" }
{ "{\it " s * "}" * }
if$
}
INTEGERS { nameptr namesleft numnames }
STRINGS {nameresult}
FUNCTION {format.names}
{ 's swap$ :=
'nameptr #1 :=
'nameresult "" :=
'numnames s num.names$ :=
'namesleft numnames :=
{ namesleft #0 > }
{
#if NAME_FULL
't s nameptr "{ff }{vv~}{ll}{, jj}" format.name$ :=
#else
't s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ :=
#endif
nameptr #1 >
{ namesleft #1 >
{ 'nameresult nameresult ", " * t * := }
{ numnames #2 >
{ 'nameresult nameresult "," * := }
'skip$
if$
t "others" =
{ 'nameresult nameresult " et al." * := }
#ifndef FRENCH
{ 'nameresult nameresult " and " * t * := }
#else FRENCH
{ 'nameresult nameresult " et " * t * := }
#endif FRENCH
if$
}
if$
}
{ 'nameresult nameresult t * := }
if$
'nameptr nameptr #1 + :=
'namesleft namesleft #1 - :=
}
while$
nameresult
}
FUNCTION {format.authors}
{ author missing$
{ "" }
{ author format.names }
if$
}
FUNCTION {format.editors}
{ editor missing$
{ "" }
{ editor num.names$ #1 >
#ifndef FRENCH
{ editor format.names ", editors" * }
{ editor format.names ", editor" * }
#else FRENCH
{ editor format.names ", \'{e}diteurs" * }
{ editor format.names ", \'{e}diteur" * }
#endif FRENCH
if$
}
if$
}
# if 0
% The format.title function is used for non-book-like titles.
% For most styles we convert to lowercase (except for the very first letter),
% and hope the user has brace-surrounded words that need to stay capitilized;
% for some, however, we leave it as it is in the database.
# endif 0
FUNCTION {format.title}
#if ATIT_LOWER
{ title missing$
{ "" }
{ title "ul" change.case$ }
if$
#else
{ title field.or.null
#endif ATIT_LOWER
}
# if 0
% The entry.string.max function is set to BibTeX's ent_str_size constant,
% the maximum length of an entry string variable.
%
% The global.string.max function is set to BibTeX's glob_str_size constant,
% the maximum length of a global string variable.
# endif 0
FUNCTION {entry.string.max} { #100 }
FUNCTION {global.string.max} { #300 }
# if 0
% The n.dashify function makes each single `-' in a string a double `--'
% if it's not already
%
% VAR: pageresult: STRING
%
% n.dashify(s) ==
% BEGIN
% t := s
% pageresult := ""
% while (not (t = ""))
% do
% if (first character of t = "-")
% then
% if (next character isn't)
% then
% pageresult := pageresult * "--"
% t := t with the "-" removed
% else
% while (first character of t = "-")
% do
% pageresult := pageresult * "-"
% t := t with the "-" removed
% od
% fi
% else
% pageresult := pageresult * the first character
% t := t with the first character removed
% fi
% od
% return pageresult
% END
# endif 0
STRINGS {pageresult}
FUNCTION {n.dashify}
{ 't swap$ :=
'pageresult "" :=
{ t "" = not }
{ t #1 #1 substring$ "-" =
{ t #1 #2 substring$ "--" = not
{ 'pageresult pageresult "--" * :=
't t #2 global.string.max substring$ :=
}
{ { t #1 #1 substring$ "-" = }
{ 'pageresult pageresult "-" * :=
't t #2 global.string.max substring$ :=
}
while$
}
if$
}
{ 'pageresult pageresult t #1 #1 substring$ * :=
't t #2 global.string.max substring$ :=
}
if$
}
while$
pageresult
}
# if 0
% The format.date function is for the month and year, but we give a warning if
% there's a missing year but the month is there, and we return the empty string
% if they're both missing
# endif 0
FUNCTION {format.date}
{ year missing$
{ month missing$
{ "" }
{ "Warning: there's a month but no year in " cite$ * top$
month
}
if$
}
{ month missing$
{ year }
{ month " " * year * }
if$
}
if$
}
# if 0
% The format.btitle is for formatting the title field when it is a book-like
% entry---the style used here keeps it in uppers-and-lowers and italicizes it.
# endif 0
FUNCTION {format.btitle}
{ title field.or.null
italicize
}
# if 0
% The format.bvolume function is for formatting the volume number and/or
% series name of a multivolume book. If the volume field is missing, we
% output either the series field italicized if it exists or the null string
% otherwise. If both the volume and series fields are there, we assume the
% series field is the title of the whole multivolume work (the title field
% should be the title of the one referred to), and add an "of <series>".
% A tie (~) is put between the "Volume" and the volume number.
% We capitilize Volume because this function is used at the beginning of a
% block.
# endif 0
FUNCTION {format.bvolume}
{ volume missing$
{ series missing$
{ "" }
{ series italicize }
if$
}
{ "Volume~" volume *
series missing$
'skip$
#ifndef FRENCH
{ " of " * series italicize * }
#else FRENCH
{ ", s\'{e}rie " * series italicize * }
#endif FRENCH
if$
}
if$
}
# if 0
% The format.edition function appends " edition" to the edition, if present.
% We lowercase the edition (it should be something like "Third"), because
% this doesn't start a sentence.
# endif 0
FUNCTION {format.edition}
{ edition missing$
{ "" }
#ifndef FRENCH
{ edition "ll" change.case$ " edition" * }
#else FRENCH
{ edition "ll" change.case$ " \'{e}dition" * }
#endif FRENCH
if$
}
# if 0
% The format.pages function is used for formatting a page range in a book
% (and in rare circumstances, an article).
% The multi.page.check function examines the page field for a "-" or a ","
% so that format.pages can use "page" instead of "pages" if neither exists.
% Note: global.string.max, set above, here means "take the rest of the string"
%
% VAR: multiresult: INTEGER (actually, a boolean)
%
% multi.page.check(s) ==
% BEGIN
% t := s
% multiresult := false
% while ((not multiresult) and (not (t = "")))
% do
% if (first character of t = "-" or ",")
% then multiresult := true
% else t := t with the first character removed
% fi
% od
% return multiresult
% END
# endif 0
INTEGERS {multiresult}
FUNCTION {multi.page.check}
{ 't swap$ :=
'multiresult #0 :=
{ multiresult not
t "" = not
and
}
{ t #1 #1 substring$ "-" =
t #1 #1 substring$ "," =
or
{ 'multiresult #1 := }
{ 't t #2 global.string.max substring$ := }
if$
}
while$
multiresult
}
# if 0
% This function doesn't begin a sentence so "pages" isn't capitalized
% other functions that use this should keep that in mind
# endif 0
FUNCTION {format.pages}
{ pages missing$
{ "" }
{ pages multi.page.check
{ "pages~" pages n.dashify * }
{ "page~" pages n.dashify * }
if$
}
if$
}
# if 0
% The format.vol.num.pages function is for the volume, number, and page range
% of a journal article. We use the format: vol(number):pages, with minor
% variations for missing fields. This doesn't begin a sentence.
# endif 0
FUNCTION {format.vol.num.pages}
{ volume field.or.null
number missing$
'skip$
{ "(" number * ")" * *
volume missing$
{ "Warning: there's a number but no volume in " cite$ * top$ }
'skip$
if$
}
if$
pages missing$
'skip$
{ duplicate$ "" =
'skip$
{ ":" * }
if$
pages n.dashify *
}
if$
}
# if 0
% The format.chapter.pages puts "chapter~" in front of a chapter number,
% if present, and then appends the pages, if present.
% This doesn't begin a sentence.
# endif 0
FUNCTION {format.chapter.pages}
{ chapter missing$
'format.pages
#ifndef FRENCH
{ "chapter~" chapter *
#else FRENCH
{ "chapitre~" chapter *
#endif FRENCH
pages missing$
'skip$
{ ", " * format.pages * }
if$
}
if$
}
# if 0
% The format.in.ed.booktitle function is used for starting out a sentence
% that begins "In <booktitle>", putting an editor before the title if one
% exists.
# endif 0
FUNCTION {format.in.ed.booktitle}
{ booktitle missing$
{ "" }
{ 's format.editors :=
s "" =
#ifndef FRENCH
{ "In " booktitle italicize * }
{ "In " s * ", " * booktitle italicize * }
#else FRENCH
{ "Dans " booktitle italicize * }
{ "Dans " s * ", " * booktitle italicize * }
#endif FRENCH
if$
}
if$
}
# if 0
% The format.tr.number makes a string starting with "Technical Report"
% (or type, if that field is defined), followed by the number if there
% is one (but return the first part even if there is no number)
# endif 0
FUNCTION {format.tr.number}
{ type missing$
#ifndef FRENCH
{ "Technical Report" }
#else FRENCH
{ "Rapport" }
#endif FRENCH
{ type }
if$
number missing$
'skip$
#ifndef FRENCH
{ "~" * number * }
#else FRENCH
{ " no.~" * number * }
#endif FRENCH
if$
}
# if 0
% Now we define the type functions for all entry types that may appear
% in the .BIB file---e.g., functions like `book' and `article'. These
% are the routines that actually generate the .BBL-file output for
% the entry. These must all precede the READ command. In addition, the
% style designer should have a function `default.type' for unknown types.
% Note: The fields (within each list) are listed in order of appearance,
% except as described for a `proceedings'.
%
% The article function is for an article in a journal.
% Required fields: author, title, journal, year
% Optional fields: volume, number, pages, month, note
%
% article ==
% BEGIN
% output.bibitem
% output.check("author",format.authors)
% new.block
% output.check("title",format.title)
% new.block
% output.check("journal",italicize(field.or.null(journal)))
% output(format.vol.num.pages)
% output.check("year",format.date)
% new.block
% output(field.or.null(note))
% fin.entry
% END
%
% The book function is for a whole book.
% Required fields: author or editor, title, publisher, year
% Optional fields: volume, series, address, edition, month, note
%
% book ==
% BEGIN
% if missing$(author) then output.check("author and editor",
% format.editors)
% else output.check("author",format.authors)
% fi
% new.block
% output.check("title",format.btitle)
% new.block
% output(format.bvolume)
% output.check("publisher",field.or.null(publisher))
% output(field.or.null(address))
% output(format.edition)
% output.check("year",format.date))
% new.block
% output(field.or.null(note))
% fin.entry
% END
%
% The other entry functions are all quite similar, so no "comment version"
% will be given for them.
# endif 0
FUNCTION {article}
{ output.bibitem
"author" format.authors output.check
new.block
"title" format.title output.check
new.block
"journal" journal field.or.null italicize output.check
format.vol.num.pages output
"year" format.date output.check
new.block
note field.or.null output
fin.entry
}
FUNCTION {book}
{ output.bibitem
author missing$
{ "author and editor" format.editors output.check }
{ "author" format.authors output.check }
if$
new.block
"title" format.btitle output.check
new.block
format.bvolume output
"publisher" publisher field.or.null output.check
address field.or.null output
format.edition output
"year" format.date output.check
new.block
note field.or.null output
fin.entry
}
# if 0
% A booklet is a bound thing without a publisher or sponsoring institution
% Required: title
% Optional: author, howpublished, address, month, year, note
# endif 0
FUNCTION {booklet}
{ output.bibitem
format.authors output
new.block
"title" format.btitle output.check
new.block
howpublished field.or.null output
address field.or.null output
format.date output
new.block
note field.or.null output
fin.entry
}
# if 0
% For the conference entry type, see inproceedings
# endif 0
# if 0
% An inbook is a piece of a book: either a chapter and/or a page range.
% Required: author or editor, title, chapter and/or pages, publisher,year
% Optional: volume, series, address, edition, month, note
# endif 0
FUNCTION {inbook}
{ output.bibitem
author missing$
{ "author and editor" format.editors output.check }
{ "author" format.authors output.check }
if$
new.block
"title" format.btitle output.check
"chapter and pages" format.chapter.pages output.check
new.block
format.bvolume output
"publisher" publisher field.or.null output.check
address field.or.null output
format.edition output
"year" format.date output.check
new.block
note field.or.null output
fin.entry
}
# if 0
% An incollection is like inbook, but where there is a separate title
% for the referenced thing (and perhaps an editor for the whole)
% Required: author, title, booktitle, publisher, year
% Optional: editor, chapter, pages, address, month, note
# endif 0
FUNCTION {incollection}
{ output.bibitem
"authors" format.authors output.check
new.block
"title" format.title output.check
new.block
"booktitle" format.in.ed.booktitle output.check
format.chapter.pages output
"publisher" publisher field.or.null output.check
address field.or.null output
"year" format.date output.check
new.block
note field.or.null output
fin.entry
}
# if 0
% An inproceedings is an article in a conference proceedings
% Required: author, title, booktitle, year
% Optional: editor, pages, organization, publisher, address, month, note
# endif 0
FUNCTION {inproceedings}
{ output.bibitem
"author" format.authors output.check
new.block
"title" format.title output.check
new.block
"booktitle" format.in.ed.booktitle output.check
format.pages output
organization field.or.null output
publisher field.or.null output
address field.or.null output
"year" format.date output.check
new.block
note field.or.null output
fin.entry
}
# if 0
% The conference function is included for Scribe compatibility
# endif 0
FUNCTION {conference} { inproceedings }
# if 0
% A manual is technical documentation
% Required: title
% Optional: author, organization, address, edition, month, year, note
# endif 0
FUNCTION {manual}
{ output.bibitem
format.authors output
new.block
"title" format.btitle output.check
new.block
organization field.or.null output
address field.or.null output
format.edition output
format.date output
new.block
note field.or.null output
fin.entry
}
# if 0
% A mastersthesis is a Master's thesis
% Required: author, title, school, year
% Optional: address, month, note
# endif 0
FUNCTION {mastersthesis}
{ output.bibitem
"author" format.authors output.check
new.block
"title" format.btitle output.check
new.block
#ifndef FRENCH
"Master's thesis" output
#else FRENCH
"Rapport de ma\^{\i}trise" output
#endif FRENCH
"school" school field.or.null output.check
address field.or.null output
"year" format.date output.check
new.block
note field.or.null output
fin.entry
}
# if 0
% added for France: rapport de DEA, like master's thesis
# endif 0
FUNCTION {deathesis}
{ output.bibitem
"author" format.authors output.check
new.block
"title" format.btitle output.check
new.block
#ifdef FRENCH
"Rapport de DEA" output
#else
"Dipl\^{o}me d'Etudes Approfondies Thesis" output
#endif FRENCH
"school" school field.or.null output.check
address field.or.null output
"year" format.date output.check
new.block
note field.or.null output
fin.entry
}
# if 0
% a misc is something that doesn't fit elsewhere
% Required: none
% Optional: author, title, howpublished, month, year, note
# endif 0
FUNCTION {misc}
{ output.bibitem
format.authors output
new.block
format.title output
new.block
howpublished field.or.null output
format.date output
new.block
note field.or.null output
fin.entry
}
# if 0
% A phdthesis is like a mastersthesis
% Required: author, title, school, year
% Optional: address, month, note
# endif 0
FUNCTION {phdthesis}
{ output.bibitem
"author" format.authors output.check
new.block
"title" format.btitle output.check
new.block
#ifndef FRENCH
"PhD thesis" output
#else FRENCH
"Th\`{e}se de Doctorat" output
#endif FRENCH
"school" school field.or.null output.check
address field.or.null output
"year" format.date output.check
new.block
note field.or.null output
fin.entry
}
# if 0
% a proceedings is a conference proceedings
% if there is an organization but no editor field, the organization will
% appear as the first optional field (we try to make the first block nonempty)
% Required: title, year
% Optional: editor, publisher, organization, address, month, note
# endif 0
FUNCTION {proceedings}
{ output.bibitem
editor missing$
{ organization missing$
'skip$
{ organization field.or.null output }
if$
}
{ format.editors output }
if$
new.block
"title" format.btitle output.check
editor missing$
'skip$
{ organization field.or.null output }
if$
publisher field.or.null output
address field.or.null output
"year" format.date output.check
new.block
note field.or.null output
fin.entry
}
# if 0
% a techreport is a technical report.
% Required: author, title, institution, year
% Optional: type, number, address, month, note
# endif 0
FUNCTION {techreport}
{ output.bibitem
"author" format.authors output.check
new.block
"title" format.btitle output.check
new.block
format.tr.number output
"institution" institution field.or.null output.check
address field.or.null output
"year" format.date output.check
new.block
note field.or.null output
fin.entry
}
# if 0
% an unpublished is something that hasn't been published
% Required: author, title, note
% Optional: month, year
# endif 0
FUNCTION {unpublished}
{ output.bibitem
"author" format.authors output.check
new.block
"title" format.title output.check
new.block
format.date output
new.block
"note" note field.or.null output.check
fin.entry
}
# if 0
% We use entry type book for an unknown type and give a warning
# endif 0
FUNCTION {default.type} { book }
# if 0
% Here are macros for common things that may vary from style to style.
% Users are encouraged to use these macros.
%
% Months are either written out in full or abbreviated
# endif 0
#if MONTH_FULL
#ifndef FRENCH
MACRO {jan} {"January"}
#else FRENCH
MACRO {jan} {"janvier"}
#endif FRENCH
#ifndef FRENCH
MACRO {feb} {"February"}
#else FRENCH
MACRO {feb} {"f\'{e}vrier"}
#endif FRENCH
#ifndef FRENCH
MACRO {mar} {"March"}
#else FRENCH
MACRO {mar} {"mars"}
#endif FRENCH
#ifndef FRENCH
MACRO {apr} {"April"}
#else FRENCH
MACRO {apr} {"avril"}
#endif FRENCH
#ifndef FRENCH
MACRO {may} {"May"}
#else FRENCH
MACRO {may} {"mai"}
#endif FRENCH
#ifndef FRENCH
MACRO {jun} {"June"}
#else FRENCH
MACRO {jun} {"juin"}
#endif FRENCH
#ifndef FRENCH
MACRO {jul} {"July"}
#else FRENCH
MACRO {jul} {"juillet"}
#endif FRENCH
#ifndef FRENCH
MACRO {aug} {"August"}
#else FRENCH
MACRO {aug} {"ao\^{u}t"}
#endif FRENCH
#ifndef FRENCH
MACRO {sep} {"September"}
#else FRENCH
MACRO {sep} {"septembre"}
#endif FRENCH
#ifndef FRENCH
MACRO {oct} {"October"}
#else FRENCH
MACRO {oct} {"octobre"}
#endif FRENCH
#ifndef FRENCH
MACRO {nov} {"November"}
#else FRENCH
MACRO {nov} {"novembre"}
#endif FRENCH
#ifndef FRENCH
MACRO {dec} {"December"}
#else FRENCH
MACRO {dec} {"d\'{e}cembre"}
#endif FRENCH
#else !MONTH_FULL
#ifndef FRENCH
MACRO {jan} {"Jan."}
#else FRENCH
MACRO {jan} {"jan."}
#endif FRENCH
#ifndef FRENCH
MACRO {feb} {"Feb."}
#else FRENCH
MACRO {feb} {"f\'{e}v."}
#endif FRENCH
#ifndef FRENCH
MACRO {mar} {"March"}
#else FRENCH
MACRO {mar} {"mars"}
#endif FRENCH
#ifndef FRENCH
MACRO {apr} {"Apr."}
#else FRENCH
MACRO {apr} {"avr."}
#endif FRENCH
#ifndef FRENCH
MACRO {may} {"May"}
#else FRENCH
MACRO {may} {"mai"}
#endif FRENCH
#ifndef FRENCH
MACRO {jun} {"June"}
#else FRENCH
MACRO {jun} {"juin"}
#endif FRENCH
#ifndef FRENCH
MACRO {jul} {"July"}
#else FRENCH
MACRO {jul} {"juil."}
#endif FRENCH
#ifndef FRENCH
MACRO {aug} {"Aug."}
#else FRENCH
MACRO {aug} {"ao\^{u}t"}
#endif FRENCH
#ifndef FRENCH
MACRO {sep} {"Sep."}
#else FRENCH
MACRO {sep} {"sep."}
#endif FRENCH
#ifndef FRENCH
MACRO {oct} {"Oct."}
#else FRENCH
MACRO {oct} {"oct."}
#endif FRENCH
#ifndef FRENCH
MACRO {nov} {"Nov."}
#else FRENCH
MACRO {nov} {"nov."}
#endif FRENCH
#ifndef FRENCH
MACRO {dec} {"Dec."}
#else FRENCH
MACRO {dec} {"d\'{e}c."}
#endif FRENCH
#endif MONTH_FULL
# if 0
% Journals are either written out in full or abbreviated;
% the abbreviations are like those found in ACM publications.
%
% To get a completely different set of abbreviations, it may be best to make
% a separate .bib file with nothing but those abbreviations; users could then
% include that file name as the first argument to the \bibliography command
# endif 0
#if JOUR_FULL
MACRO {acmcs} {"ACM Computing Surveys"}
MACRO {acta} {"Acta Informatica"}
MACRO {cacm} {"Communications of the ACM"}
MACRO {ibmjrd} {"IBM Journal of Research and Development"}
MACRO {ibmsj} {"IBM Systems Journal"}
MACRO {ieeese} {"IEEE Transactions on Software Engineering"}
MACRO {ieeetc} {"IEEE Transactions on Computers"}
MACRO {ieeetcad}
{"IEEE Transactions on Computer-Aided Design of Integrated Circuits"}
MACRO {ipl} {"Information Processing Letters"}
MACRO {jacm} {"Journal of the ACM"}
MACRO {jcss} {"Journal of Computer and System Sciences"}
MACRO {scp} {"Science of Computer Programming"}
MACRO {sicomp} {"SIAM Journal on Computing"}
MACRO {tocs} {"ACM Transactions on Computer Systems"}
MACRO {tods} {"ACM Transactions on Database Systems"}
MACRO {tog} {"ACM Transactions on Graphics"}
MACRO {toms} {"ACM Transactions on Mathematical Software"}
MACRO {toois} {"ACM Transactions on Office Information Systems"}
MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"}
MACRO {tcs} {"Theoretical Computer Science"}
#ifdef FRENCH
MACRO {tsi} {"Technique et Science Informatiques"}
#endif FRENCH
#else !JOUR_FULL
MACRO {acmcs} {"ACM Comput. Surv."}
MACRO {acta} {"Acta Inf."}
MACRO {cacm} {"Commun. ACM"}
MACRO {ibmjrd} {"IBM J. Res. Dev."}
MACRO {ibmsj} {"IBM Syst. J."}
MACRO {ieeese} {"IEEE Trans. Softw. Eng."}
MACRO {ieeetc} {"IEEE Trans. Comput."}
MACRO {ieeetcad}
{"IEEE Trans. Comput.-Aided Design Integrated Circuits"}
MACRO {ipl} {"Inf. Process. Lett."}
MACRO {jacm} {"J. ACM"}
MACRO {jcss} {"J. Comput. Syst. Sci."}
MACRO {scp} {"Sci. Comput. Programming"}
MACRO {sicomp} {"SIAM J. Comput."}
MACRO {tocs} {"ACM Trans. Comput. Syst."}
MACRO {tods} {"ACM Trans. Database Syst."}
MACRO {tog} {"ACM Trans. Gr."}
MACRO {toms} {"ACM Trans. Math. Softw."}
MACRO {toois} {"ACM Trans. Office Inf. Syst."}
MACRO {toplas} {"ACM Trans. Prog. Lang. Syst."}
MACRO {tcs} {"Theoretical Comput. Sci."}
MACRO {tsi} {"Technique et Science Informatiques"}
#endif JOUR_FULL
# if 0
% Now we read in the .BIB entries.
# endif 0
READ
# if 0
% The sortify function converts to lower case after purify$ing; it's
% used in sorting and in computing alphabetic labels after sorting
# endif 0
#if SORTED
FUNCTION {sortify}
{ purify$
"ll" change.case$
}
#endif SORTED
# if 0
% This long comment applies only to alphabetic labels
%
% The format.lab.names function makes a short label by using the initials of
% the von and Last parts of the names (but if there are more than four names,
% (i.e., people) it truncates after three and adds a "*";
% it also adds a "*" if the last of multiple authors is "others").
% If there is only one name, and its von and Last parts combined have just
% a single name-token ("Knuth" has a single token, "Brinch Hansen" has two),
% we take the first three letters of the last name.
% In the LONG and ALPHA3 styles, only the name of the first author is
% considered.
% In the KEY and SKEY styles, the label is equal to the citation key.
%
% format.lab.names(s) ==
% BEGIN
% numnames := num.names$(s)
% if numnames > 1 then
% if numnames > 4 then
% namesleft := 3
% else
% namesleft := numnames
% nameptr := 1
% nameresult := ""
% while namesleft > 0
% do
% if (name_ptr = numnames) and
% format.name$(s, nameptr, "{ff}{vv}{ll}{jj}") = "others"
% then nameresult := nameresult * "*"
% else nameresult := nameresult *
% format.name$(s, nameptr, "{v{}}{l{}}")
% nameptr := nameptr + 1
% namesleft := namesleft - 1
% od
% if numnames > 4 then
% nameresult := nameresult * "*"
% else
% t := format.name$(s, 1, "{v{}}{l{}}")
% if substring$(t, 2, 1) = "" then % there's just one name-token
% nameresult := substring$(purify$(format.name$(s, 1, "{ll}")),
% 1, 3)
% else
% nameresult := t
% fi
% fi
% nameresult
% END
%
% Here is a function for calculating the preliminary label of an entry.
% It is formed by calculating format.lab.names on the author field
% (or on the editor field if there is no author, or using the first three
% letters of the key field if there is no editor either), and appending the
% last two characters (digits) of the year. It is an error if there is no
% author, editor or key field, and we use the first three letters of the title
% in desperation when this happens. The resulting label is purify$ed, except
% for possibly a "*" if there are too many authors.
%
% This function also calculates the version of this label to be used in sorting
%
% The final label may need a trailing 'a', 'b', etc., to distinguish it from
% otherwise identical labels, but we can't calculated those "extra.label"s
% until after sorting.
%
% calc.label ==
% BEGIN
% if missing$(author) then
% if missing$(editor) then
% if missing$(key) then
% top$("Warning: need a key to make a label in " * cite$)
% label := substring$(purify$(field.or.null(title)), 1, 3)
% else
% label := substring$(purify$(key), 1, 3)
% fi
% else
% label := format.lab.names(editor)
% fi
% else
% label := format.lab.names(author)
% fi
% label := label * substring$(purify$(field.or.null(year)), -1, 2)
% % assuming we will also sort, we calculate a sort.label
% sort.label := sortify(label)
% END
%
% In the case of the SKEY style, compute the sort.label as above, but do
% label := cite$
% In the case of the KEY style, the above computation is done but not used.
% It really should be taken out, but what the heck.
# endif 0
#if LAB_ALPH
FUNCTION {format.lab.names}
{ 's swap$ :=
#if !ALPHA_LONG
'numnames s num.names$ :=
numnames #1 >
{ numnames #4 >
{ 'namesleft #3 := }
{ 'namesleft numnames := }
if$
'nameptr #1 :=
'nameresult "" :=
{ namesleft #0 > }
{ nameptr numnames =
{ s nameptr "{ff}{vv}{ll}{jj}" format.name$ "others" =
{ 'nameresult nameresult "*" * := }
{ 'nameresult nameresult s nameptr "{v{}}{l{}}" format.name$
* :=
}
if$
}
{ 'nameresult nameresult s nameptr "{v{}}{l{}}" format.name$
* :=
}
if$
'nameptr nameptr #1 + :=
'namesleft namesleft #1 - :=
}
while$
numnames #4 >
{ 'nameresult nameresult "*" * := }
'skip$
if$
}
{
#endif ALPHA_LONG
't s #1 "{v{}}{l{}}" format.name$ :=
'nameresult
t #2 #1 substring$ "" =
#if ALPHA_LONG<2
{ s #1 "{ll}" format.name$ purify$ #1 #3 substring$ }
#else ALPHA_LONG
{ s #1 "{ll}" format.name$ purify$ }
#endif ALPHA_LONG
{ t }
if$
:=
#if !ALPHA_LONG
}
if$
#endif ALPHA_LONG
nameresult
}
FUNCTION {calc.label}
{ 'label
author missing$
{ editor missing$
{ key missing$
{ "Warning: need a key to make a label in " cite$ * top$
title field.or.null purify$ #1 #3 substring$
}
{ key purify$ #1 #3 substring$ }
if$
}
{ editor format.lab.names }
if$
}
{ author format.lab.names }
if$
#ifdef PAREN
" (" year field.or.null purify$ #-1 #2 substring$ * ")" *
#else !PAREN
# if ALPHA_LONG>1
" " year field.or.null purify$ #-1 #2 substring$ *
# else ALPHA_LONG<=1
year field.or.null purify$ #-1 #2 substring$
# endif ALPHA_LONG
#endif PAREN
*
:=
#if SORTED
'sort.label label sortify :=
#endif SORTED
#if LBKEYS
'label cite$ :=
#endif LBKEYS
}
# if 0
% It doesn't seem like a particularly good idea to use an order-of-citation
% reference list when using alphabetic labels, but we need to have a
% special pass to calculate labels when this happens.
# endif 0
#if !SORTED
ITERATE {calc.label}
#endif !SORTED
#endif LAB_ALPH
# if 0
% When sorting, we compute the sortkey by executing "presort" on each entry.
% The presort key contains a number of "sortify"ed strings, concatenated
% with multiple blanks between them. This makes things like "brinch per"
% come before "brinch hansen per"
%
% The fields used here are:
% the sort.label for alphabetic labels (as set by calc.label),
% followed by the author names (or editor names, if those are missing,
% or the key field if both are), followed by the first bit
% of the title (chopping off a leading "The ", "A ", or "An ").
% Names are formatted: Von Last First Junior.
% The names within a part will be separated by a single blank
% (such as "brinch hansen"), two will separate the name parts themselves
% (except the von and last), three will separate the names,
% and four will separate the names from the title (and label, if alphabetic).
%
% The sort.format.names function takes an argument that should be in
% BibTeX name format, and returns a string containing " "-separated
% names in the format described above. The function is almost the same
% as format.names.
# endif 0
#if SORTED
FUNCTION {sort.format.names}
{ 's swap$ :=
'nameptr #1 :=
'nameresult "" :=
'numnames s num.names$ :=
'namesleft numnames :=
{ namesleft #0 > }
{ nameptr #1 >
{ 'nameresult nameresult " " * := }
'skip$
if$
#if NAME_FULL
't s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ :=
#else
't s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ :=
#endif NAME_FULL
nameptr numnames = t "others" = and
{ 'nameresult nameresult "et al" * := }
{ 'nameresult nameresult t sortify * := }
if$
'nameptr nameptr #1 + :=
'namesleft namesleft #1 - :=
}
while$
nameresult
}
# if 0
% The chop.word(w,len,s) function returns either s or, if the first len
% letters of s equals w (this comparison is done in the third line of the
% function's definition), it returns that part of s after w.
# endif 0
INTEGERS {len}
FUNCTION {chop.word}
{ 's swap$ :=
'len swap$ :=
s #1 len substring$ =
{ s len #1 + global.string.max substring$ }
{ s }
if$
}
# if 0
% The sort.format.title function returns the argument,
% but first any leading "A "'s, "An "'s, or "The "'s are removed.
% The chop.word function uses s, so we need another string variable, t
# endif 0
FUNCTION {sort.format.title}
{ 't swap$ :=
"A " #2
"An " #3
"The " #4 t chop.word
chop.word
chop.word
#1 global.string.max substring$
sortify
}
# if 0
% There is a limit on the length of an entry string variable, which
% is what its sort.key$ is. The limit is currently entry.string.max, so we
% take at most that many characters of the constructed key, and hope
% there aren't many references that match to that many characters!
# endif 0
FUNCTION {presort}
{
#if LAB_ALPH
calc.label
sort.label
" "
*
#endif LAB_ALPH
author missing$
{ editor missing$
{ key field.or.null sortify }
{ editor sort.format.names }
if$
}
{ author sort.format.names }
if$
#if LAB_ALPH
*
#endif LAB_ALPH
" "
*
title field.or.null
sort.format.title
*
#1 entry.string.max substring$
'sort.key$ swap$ :=
}
ITERATE {presort}
# if 0
% And now we can sort
# endif 0
SORT
#endif SORTED
# if 0
% This long comment applies only to alphabetic labels, when sorted
%
% Now comes the final computation for alphabetic labels, putting in the 'a's
% and 'b's and so forth if required. This involves two passes: a forward
% pass to put in the 'b's, 'c's and so on, and a backwards pass
% to put in the 'a's (we don't want to put in 'a's unless we know there
% are 'b's). However this is not necessary in the 'skeys' style.
% We have to keep track of the longest (in width$ terms) label, for use
% by the "thebibliography" environment.
%
% VAR: longest.label, last.sort.label, next.extra: string
% longest.label.width, last.extra.num: integer
%
% initialize.longest.label ==
% BEGIN
% longest.label := ""
% last.sort.label := ""
% next.extra := ""
% longest.label.width := 0
% last.extra.num := 0
% END
%
% forward.pass ==
% BEGIN
% if last.sort.label = sort.label then
% last.extra.num := last.extra.num + 1
% extra.label := int.to.chr$(last.extra.num)
% else
% last.extra.num := chr.to.int$("a")
% extra.label := ""
% last.sort.label := sort.label
% fi
% END
%
% reverse.pass ==
% BEGIN
% if next.extra = "b" then
% extra.label := "a"
% fi
% label := label * extra.label
% if width$(label) > longest.label.width then
% longest.label := label
% longest.label.width := width$(label)
% fi
% next.extra := extra.label
% END
# endif 0
#if LAB_ALPH
#if SORTED
STRINGS { longest.label last.sort.label next.extra }
INTEGERS { longest.label.width last.extra.num }
FUNCTION {initialize.longest.label}
{ 'longest.label "" :=
'last.sort.label "" :=
'next.extra "" :=
'longest.label.width #0 :=
'last.extra.num #0 :=
}
# ifndef SKEY
FUNCTION {forward.pass}
{ last.sort.label sort.label =
{ 'last.extra.num last.extra.num #1 + :=
'extra.label last.extra.num int.to.chr$ :=
}
{ 'last.extra.num "a" chr.to.int$ :=
'extra.label "" :=
'last.sort.label sort.label :=
}
if$
}
# endif SKEY
FUNCTION {reverse.pass}
{
# ifndef SKEY
next.extra "b" =
{ 'extra.label "a" := }
'skip$
if$
'label label extra.label * :=
# endif SKEY
label width$ longest.label.width >
{ 'longest.label label :=
'longest.label.width label width$ :=
}
'skip$
if$
'next.extra extra.label :=
}
EXECUTE {initialize.longest.label}
# ifndef SKEY
ITERATE {forward.pass}
# endif SKEY
REVERSE {reverse.pass}
#else !SORTED
# if 0
% It still doesn't seem like a good idea to use an order-of-citation
% reference list when using alphabetic labels, but when this happens we
% must compute the longest label
# endif 0
STRINGS {longest.label}
INTEGERS {longest.label.width}
FUNCTION {initialize.longest.label}
{ 'longest.label "" :=
'longest.label.width #0 :=
}
FUNCTION {longest.label.pass}
{ label width$ longest.label.width >
{ 'longest.label label :=
'longest.label.width label width$ :=
}
'skip$
if$
}
EXECUTE {initialize.longest.label}
ITERATE {longest.label.pass}
#endif SORTED
#else !LAB_ALPH
# if 0
% Now comes the computation for numeric labels.
% We use either the sorted order or original order.
% We still have to keep track of the longest (in width$ terms) label, for use
% by the "thebibliography" environment.
# endif 0
STRINGS {longest.label}
INTEGERS { number.label longest.label.width }
FUNCTION {initialize.longest.label}
{ 'longest.label "" :=
'number.label #1 :=
'longest.label.width #0 :=
}
FUNCTION {longest.label.pass}
{ 'label number.label int.to.str$ :=
'number.label number.label #1 + :=
label width$ longest.label.width >
{ 'longest.label label :=
'longest.label.width label width$ :=
}
'skip$
if$
}
EXECUTE {initialize.longest.label}
ITERATE {longest.label.pass}
#endif LAB_ALPH
# if 0
% Now we're ready to start writing the .BBL file.
% First we write the `preamble' containing the command
% \begin{thebibliography}{...}
% where the `...' is the longest label.
%
% Then we call init.state.consts, for use by the output routines.
# endif 0
FUNCTION {preamble}
{ "\begin{thebibliography}{" longest.label * "}" * write$
newline$
}
EXECUTE {preamble}
EXECUTE {init.state.consts}
# if 0
% Now we produce the output for all the entries
# endif 0
ITERATE {call.type$}
# if 0
% Finally, we finish up by writing the `\end{thebibliography}' command.
# endif 0
FUNCTION {finish.up} { newline$ "\end{thebibliography}" write$ newline$ }
EXECUTE {finish.up}